<?php

namespace App\Http\Service;

use App\Contract\ContractStatus;
use App\Contract\OrderType;
use App\Contract\Platform;
use App\Model\Bill;
use App\Model\BillPay;
use App\Model\Contract;
use App\Model\Device;
use App\Model\DeviceLog;
use App\Utils\Token;
use Guzzle\Http\Client;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Log;

class DeviceService
{
    protected PendingRequest $client;

    public function __construct(PendingRequest $client)
    {
        $this->client = $client;
    }

    # 查询
    public function statusQuery($mac)
    {
        return $this->post('/device/statusQuery', ['mac' => $mac]);
    }

    # 拉闸
    public function stop($mac)
    {
        return $this->post('/device/stop', ['mac' => $mac]);
    }

    # 合闸
    public function start($mac)
    {
        return $this->post('/device/start', ['mac' => $mac]);
    }

    public function warningCurr($mac,$warning_curr)
    {
        return $this->post('/device/curr', ['mac' => $mac,'warning_curr'=>$warning_curr]);
    }

    public function setMode($mac,$type)
    {
        return $this->post('/device/setMode', ['mac' => $mac,'type' => $type]);
    }

    public function setTotal($mac,$value)
    {
        return $this->post('/device/setTotal', ['mac' => $mac,'value' => $value]);
    }

    # 重启
    public function restart($mac)
    {
        return $this->post('/device/restart', ['mac' => $mac]);
    }

    public function editDu($mac,$du){
        return $this->post('/device/editDu', ['mac' => $mac, 'du' => $du * 1000]);
    }

    public function sendFgb($mac,$data){
        return $this->post('/device/makeFg', ['mac' => $mac, 'data' => json_encode($data,true)]);
    }

    # 充值
    public function recharge($mac, $du, $amount, $isRecharged, $isPaid)
    {
        $device = $this->getDeviceByMac($mac);
        $before = $device->du;
        if ($device->client_id && !$isRecharged) {
            $result = $this->post('/device/recharge', ['mac' => $mac, 'du' => $du * 1000]);
            Log::notice('recharge', [$mac, $du, $result]);
            if (!$result) {
                return false;
            }
        }
        if (!$isPaid) {
            $this->addBill($device, $du, $amount);
        }
        if($device->type == 2){
            $str = '房东水费充值';
        }else{
            $str = '房东电量充值';
        }
        // 写入充值日志
        DeviceLog::create([
            'action' => 3,
           'device_id' => $device->id,
            'log' => $str,
            'amount' => $amount,
           'user_name' => $this->getUserName(),
            'before'=>$before,
            'after' =>round($before+$du,2)
        ]);
        $device->total_money += $amount;
        $device->total_recharge += 1;
        $device->save();
        return true;
    }


    public function rechargeNoBill($mac, $du, $amount, $isRecharged, $isPaid)
    {
        $device = $this->getDeviceByMac($mac);
        $before = $device->du;
        if ($device->client_id && !$isRecharged) {
            $result = $this->post('/device/recharge', ['mac' => $mac, 'du' => $du * 1000]);
            Log::notice('recharge', [$mac, $du, $result]);
            if (!$result) {
                return false;
            }
        }
        if($device->type == 2){
            $str = '房东水费充值';
        }else{
            $str = '房东电量充值';
        }
        // 写入充值日志
        DeviceLog::create([
            'action' => 3,
            'device_id' => $device->id,
            'log' => $str,
            'amount' => $amount,
            'user_name' => $this->getUserName(),
            'before'=>$before,
            'after' =>round($before+$du,2)
        ]);
        $device->total_money += $amount;
        $device->total_recharge += 1;
        $device->save();
        return true;
    }

    # 充值
    public function rechargeAgent($mac, $du, $amount, $isRecharged, $isPaid)
    {
        $device = $this->getDeviceByMac($mac);
        $before = $device->du;
        if ($device->client_id && !$isRecharged) {
            $result = $this->post('/device/recharge', ['mac' => $mac, 'du' => $du * 1000]);
            Log::notice('recharge', [$mac, $du, $result]);
            if (!$result) {
                return false;
            }
        }
        if (!$isPaid) {
            $this->addBill($device, $du, $amount);
        }
        // 写入充值日志
//        DeviceLog::create([
//            'action' => 3,
//            'device_id' => $device->id,
//            'log' => '商户电量充值',
//            'amount' => $amount,
//            'user_name' => $this->getUserName(),
//            'before'=>$before,
//            'after' =>round($before+$du,2)
//        ]);
        Log::info('商户充值打印'.json_encode(
                [
                    'action' => 3,
                    'device_id' => $device->id,
                    'log' => '商户电量充值',
                    'amount' => $amount,
                    'user_name' => $this->getUserName(),
                    'before'=>$before,
                    'after' =>round($before+$du,2)
                ]
            ));
        $device->total_money += $amount;
        $device->total_recharge += 1;
        $device->save();
        return true;
    }

    # 仅充值
    public function simpleRecharge($mac, $du, $amount)
    {
        $device = $this->getDeviceByMac($mac);
        if ($device->client_id) {
            $result = $this->post('/device/recharge', ['mac' => $mac, 'du' => $du * 1000]);
            Log::notice('recharge', [$mac, $du, $result]);
            if (!$result) {
                return false;
            }
        }
        return true;
    }


    public function secondRecharge($mac, $du, $amount)
    {
        $device = $this->getDeviceByMac($mac);
        if ($device->client_id) {
            $result = $this->post('/device/finalDu', ['mac' => $mac, 'du' => $du * 1000]);
            if (!$result) {
                return false;
            }
        }
    }

    # 房东充值也增加账单记录
    public function addBill($device, $du, $amount)
    {
        // 找出租客的手机
        $contract = Contract::where('house_id', $device->house_id)->where('status', '>', ContractStatus::DAIQIANYUE)->with('masterTenant')->first();
        $mobile = $contract->masterTenant->mobile ?? '';
        // 生成电费账单
        $bill = new Bill();
        if($device->type == 2){
            $type = OrderType::WATER;
            $str = '水费充值：' . $du . '吨';
        }else{
            $type =OrderType::ELECTRIC;
            $str = '电量充值：' . $du . '度';
        }
        $bill->fill([
            'business_id' => $device->business_id,
            'mobile' => $mobile,
            'house_id' => $device->house_id,
            'device_id' => $device->id,
            'title' => $str,
            'amount' => $amount,
            'type' => $type,
            'is_paid' => 1,
            'paid_at' => now()->toDateTimeString(),
            'target_id'=>'u_'.time().rand(0,999)
        ]);
        $bill->save();
        $billPay = new BillPay();
        $billPay->fill([
            'sn' => 'SD' . date('ymdHis') . rand(1000, 9999),
            'bill_id' => $bill->id,
            'amount' => $amount,
            'payment' => 0,
            'is_paid' => 1,
            'paid_at' => now()->toDateTimeString(),
        ]);
        $billPay->save();
    }

    # 增加设备充值成功日志
    public function addRechargeLog($id, $du, $amount,$user=null,$time)
    {
        $device = Device::query()->where('id',$id)->first();
        if($device){
            $device->total_money += $amount;
            $device->month_recharge += $amount;
            $device->total_recharge += 1;
            $device->total_du+=$du;
            if($du > 0){
                if(!$user){
                    $device->mobile = Token::getUser()->mobile;
                }else{
                    $device->mobile = $user->mobile;
                }
            }
            $device->save();
        }
        if($user){
            $userName = $user->nickame;
            if(!$userName){
                $userName = $user->mobile;
            }
        }else{
            $userName = $this->getUserName();
        }
        if($device->type == 2){
            $str = '租客水费充值' . $du . '吨';
        }else{
            $str =  '租客电量充值' . $du . '度';
        }
        // 写入充值日志
        DeviceLog::create([
           'action' => 3,
           'device_id' => $id,
           'log' => $str,
           'amount' => $amount,
           'user_name' => $userName,
            'before'=>round($device->du-$du,2),
            'after'=>$device->du,
            'created_at'=>$time
        ]);
    }

    # 增加设备充值成功日志
    public function addRechargeFailLog($id, $du, $amount,$before = 0,$after =0)
    {
        $device = Device::query()->where('id',$id)->first();
        if($device->type == 2) {
            $str = '租客水费充值失败：' . $du . '吨';
        }else{
            $str = '租客电量充值失败：' . $du . '度';
        }
            // 写入充值日志
        DeviceLog::create(['action' => 4,
           'device_id' => $id,
           'log' => $str,
           'amount' => $amount,
           'user_name' => $this->getUserName(),
           'before'=>$before,
           'after'=>$after
        ]);
    }

    public function clear($mac, $type = 1)
    {
        $device = $this->getDeviceByMac($mac);
        $before = $device->du;
        if ($device->client_id) {
            $result = $this->post('/device/clear', ['mac' => $mac, 'type' => $type]);
            Log::notice('clear result', [$result]);
            if (!$result) {
                return false;
            }
        } else {
            $device->du = 0;
            $device->save();
        }

//        if($device->type == 2){
//            $str = '水费手动清零';
//        }else{
//            $str = '电量手动清零';
//        }
//        // 写入清 0 日志
//        DeviceLog::create([
//            'action' => 1,
//           'device_id' => $device->id,
//            'log' => $str,
//           'user_name' => $this->getUserName(),
//            'before'=>$before,
//            'after'=>0
//        ]);
        return true;
    }

    public function speed($mac, $speed)
    {
        $device = $this->getDeviceByMac($mac);
        if ($device->client_id) {
            $result = $this->post('/device/speed', ['mac' => $mac, 'speed'=> $speed]);
            if (!$result) {
                return false;
            }
        }
        $device->speed = $speed;
        $device->save();

        // 写入清 0 日志
        DeviceLog::create([
            'action' => 2,
            'device_id' => $device->id,
            'log' => '调表：' . $speed,
            'user_name' => $this->getUserName()
        ]);
        return true;
    }

    public function querySpeed($mac)
    {
        $device = $this->getDeviceByMac($mac);
        if ($device->client_id) {
            $result = $this->post('/device/querySpeed', ['mac' => $mac]);
            if (!$result) {
                return false;
            }
        }
        return true;
    }

    public function getDeviceByMac($mac)
    {
        $device = Device::query()->where('mac', $mac)->first();
        if (!$device) {
            throw new \Exception('设备号不存在', 400);
        }
        return $device;
    }

    public function post($url, $data)
    {
        $response = $this->client->post($url, $data);
        if ($response->body() != 'ok') {
            throw new \Exception('设备通迅失败，请稍后再试', 500);
        }
        return true;
    }

    public function getUserName()
    {
        if (Token::getPlatform() === Platform::SAAS) {
            return Token::getUser()->name;
        }
        if (Token::getPlatform() === Platform::MP) {
            return Token::getUser()->nickname ?? Token::getUser()->mobile;
        }
        return '-';
    }
}
